<template>
    <el-main>
        <el-button type="success" size="small" @click="openAddWindow()" icon="el-icon-plus" v-if="$hasPermission('sys:menu:add')">新增</el-button>

        <el-table style="margin-top: 10px;" :height="tableHeight" :data="menuList" row-key="id" default-expand-all
            :tree-props="{ children: 'children' }" :border="true" stripe>
            <el-table-column prop="label" label="菜单名称"></el-table-column>
            <el-table-column prop="type" label="菜单类型" align="center">
                <template slot-scope="scope">
                    <el-tag v-if="scope.row.type == '0'" size="normal">目录</el-tag>
                    <el-tag type="success" v-else-if="scope.row.type == '1'" size="normal">菜单</el-tag>
                    <el-tag type="warning" v-else-if="scope.row.type == '2'" size="normal">按钮</el-tag>
                </template>
            </el-table-column>
            <el-table-column prop="icon" label="图标" align="center">
                <template slot-scope="scope">
                    <i :class="scope.row.icon" v-if="scope.row.icon.includes('el-icon')"></i>
                    <svg-icon v-else :icon-class="scope.row.icon"></svg-icon>
                </template>
            </el-table-column>
            <el-table-column prop="name" label="路由名称"></el-table-column>
            <el-table-column prop="path" label="路由地址"></el-table-column>
            <el-table-column prop="url" label="组件路径"></el-table-column>
            <el-table-column label="操作" align="center">
                <template slot-scope="scope">
                    <el-button type="primary" icon="el-icon-edit" size="small" @click="editMenu(scope.row)" v-if="$hasPermission('sys:menu:edit')">编辑</el-button>
                    <el-button type="danger" icon="el-icon-delete" size="small"
                        @click="deleteMenu(scope.row)" v-if="$hasPermission('sys:menu:delete')">删除</el-button>
                </template>
            </el-table-column>
        </el-table>

        <system-dialog :title="menuDialog.title" :width="menuDialog.width" :height="menuDialog.height"
            :visible="menuDialog.visible" @onClose="onClose()" @onConfirm="onConfirm()">
            <div slot="content">
                <el-form :model="menu" ref="menuForm" :rules="rules" label-width="80px" :inline="true" size="small">
                    <el-col :span="24">
                        <el-form-item prop="type" label="菜单类型">
                            <el-radio-group v-model="menu.type">
                                <el-radio :label="0">目录</el-radio>
                                <el-radio :label="1">菜单</el-radio>
                                <el-radio :label="2">按钮</el-radio>
                            </el-radio-group>
                        </el-form-item>
                    </el-col>
                    <el-form-item label="所属菜单" size="small" prop="parentName">
                        <el-input v-model="menu.parentName" :readonly="true" @click.native="selectParentMenu()"></el-input>
                    </el-form-item>
                    <el-form-item label="菜单名称" size="small" prop="label">
                        <el-input v-model="menu.label"></el-input>
                    </el-form-item>
                    <el-form-item label="路由名称" size="small" prop="name" v-if="menu.type === 1">
                        <el-input v-model="menu.name"></el-input>
                    </el-form-item>
                    <el-form-item label="路由地址" size="small" prop="path" v-if="menu.type !== 2">
                        <el-input v-model="menu.path"></el-input>
                    </el-form-item>
                    <el-form-item label="组件路径" size="small" prop="url" v-if="menu.type === 1">
                        <el-input v-model="menu.url"></el-input>
                    </el-form-item>
                    <el-form-item label="权限字段" size="small" prop="code">
                        <el-input v-model="menu.code"></el-input>
                    </el-form-item>
                    <el-form-item label="菜单图标" size="small">
                        <my-icon @selecticon="setIcon" ref="child"></my-icon>
                    </el-form-item>
                    <el-form-item label="菜单序号" size="small">
                        <el-input v-model="menu.orderNum"></el-input>
                    </el-form-item>
                </el-form>
            </div>
        </system-dialog>

        <system-dialog :title="parentDialog.title" :width="parentDialog.width" :height="parentDialog.height"
            :visible="parentDialog.visible" @onClose="onParentClose()" @onConfirm="onParentConfirm()">
            <div slot="content">
                <el-tree style="font-size: 14px;" ref="parentTree" :data="parentList" node-key="id" :props="defaultProps"
                    empty-text="暂无数据" :show-checkbox="false" default-expand-all :highlight-current="false"
                    @node-click="handleNodeClick">
                    <div class="customer-tree-node" slot-scope="{ node, data}">
                        <span v-if="data.children.length === 0">
                            <i class="el-icon-document" style="color: #8c8c8c; font-size: 18px;"></i>
                        </span>
                        <span v-else @click.stop="changeIcon(data)">
                            <svg-icon v-if="data.open" icon-class="add-s"></svg-icon>
                            <svg-icon v-else icon-class="sub-s"></svg-icon>
                        </span>
                        <span style="margin-left: 3px;">{{ node.label }}</span>
                    </div>
                </el-tree>
            </div>
        </system-dialog>
    </el-main>
</template>

<script>
import menuApi from '@/api/menu'
import SystemDialog from '@/components/system/SystemDialog.vue'
import MyIcon from '@/components/system/MyIcon.vue'

export default {
    name: "menuList",
    components: {
        SystemDialog,
        MyIcon
    },
    data() {
        return {
            tableHeight: 0,
            menuList: [],
            menu: {
                id: "",
                type: "",
                parentId: "",
                parentName: "",
                label: "",
                icon: "",
                name: "",
                path: "",
                url: "",
                code: "",
                orderNum: ""
            },
            menuDialog: {
                title: "",
                width: 630,
                height: 270,
                visible: false,
                type: 'add'
            },
            parentDialog: {
                title: "",
                width: 280,
                height: 450,
                visible: false
            },
            rules: {
                type: [{ required: true, message: "请选择菜单类型", trigger: "change" }],
                parentName: [{ required: true, message: "请选择父权限", trigger: "change" }],
                label: [{ required: true, message: "请输入菜单名称", trigger: "blur" }],
                name: [{ required: true, message: "请输入路由名称", trigger: "blur" }],
                path: [{ required: true, message: "请输入路由路径", trigger: "blur" }],
                url: [{ required: true, message: "请输入组件路径", trigger: "blur" }],
                code: [{ required: true, message: "请输入权限字段", trigger: "blur" }]
            },
            defaultProps: {
                children: "children",
                label: "label"
            },
            parentList: []
        }
    },
    created() {
        this.search()
    },
    mounted() {
        this.$nextTick(() => {
            this.tableHeight = window.innerHeight - 180
        })
    },
    methods: {
        async search() {
            let res = await menuApi.getMenuList()
            if (res.success) {
                this.menuList = res.data
            }
        },
        openAddWindow() {
            this.$resetForm('menuForm', this.menu)
            this.menuDialog.title = "新增菜单"
            this.menuDialog.visible = true
            this.menuDialog.type = 'add'
            this.$nextTick(() => {
                this.$refs['child'].userChooseIcon = ''
            })
        },
        editMenu(row) {
            this.$objCopy(row, this.menu)
            this.menuDialog.title = "修改菜单"
            this.menuDialog.visible = true
            this.menuDialog.type = 'edit'
            this.$nextTick(() => {
                this.$refs['child'].setIcon(this.menu.icon)
            })
        },
        async deleteMenu(row) {
            let check = await menuApi.checkPermission({ id: row.id })
            if (!check.success) {
                this.$message.warning("菜单不存在, 无法删除")
            } else {
                let confirm = await this.$myconfirm("确定要删除该数据吗?")
                if (confirm) {
                    let res = await menuApi.deleteById({ id: row.id })
                    if (res.success) {
                        this.$message.success(res.message)
                        this.search()
                    } else {
                        this.$message.error(res.message)
                    }
                }
            }
        },
        onClose() {
            this.menuDialog.visible = false
        },
        onConfirm() {
            if (this.menuDialog.type === 'add') {
                this.$refs.menuForm.validate(async valid => {
                    if (valid) {
                        let res = await menuApi.addMenu(this.menu)
                        if (res.success) {
                            this.$message.success(res.message)
                            this.menuDialog.visible = false
                            this.search()
                        } else {
                            this.$message.error(res.message)
                        }
                    }
                })
            } else if (this.menuDialog.type === 'edit') {
                this.$refs.menuForm.validate(async valid => {
                    if (valid) {
                        let res = await menuApi.updateMenu(this.menu)
                        if (res.success) {
                            this.$message.success(res.message)
                            this.menuDialog.visible = false
                            this.search()
                        } else {
                            this.$message.error(res.message)
                        }
                    }
                })
            }

        },
        setIcon(icon) {
            this.menu.icon = icon
        },
        async selectParentMenu() {
            let res = await menuApi.getParentMenuList()
            if (res.success) {
                this.parentList = res.data
            }
            this.parentDialog.title = "选择所属菜单"
            this.parentDialog.visible = true
        },
        onParentClose() {
            this.parentDialog.visible = false
        },
        onParentConfirm() {
            this.parentDialog.visible = false
        },
        handleNodeClick(node) {
            this.menu.parentId = node.id
            this.menu.parentName = node.label
        },
        changeIcon(data) {
            data.open = !data.open
            this.$refs.parentTree.store.nodesMap[data.id].expanded = !data.open
        }
    }
}
</script>

<style lang="scss" scoped>
::v-deep .el-tree {
    .el-tree-node {
        position: relative;
        padding-left: 10px;
    }

    .el-tree-node__children {
        padding-left: 20px;
    }

    .el-tree-node :last-child::before {
        height: 40px;
    }

    .el-tree>.el-tree-node::before {
        border-left: none;
    }

    .el-tree>.el-tree-node::after {
        border-top: none;
    }

    .el-tree-node::before,
    .el-tree-node::after {
        content: "";
        left: -4px;
        position: absolute;
        right: auto;
        border-width: 1px;
    }

    .tree :first-child .el-tree-node::before {
        border-left: none;
    }

    .el-tree-node::before {
        border-left: 1px dotted #d9d9d9;
        bottom: 0px;
        height: 100%;
        top: -25px;
        width: 24px;
    }

    .el-tree-node__expand-icon.is-leaf {
        width: 8px;
    }

    .el-tree-node__content>.el-tree-node__expand-icon {
        display: none;
    }

    .el-tree-node__content {
        line-height: 30px;
        height: 30px;
        padding-left: 10px !important;
    }
}

::v-deep .el-tree>div {
    &::before {
        display: none;
    }

    &::after {
        display: none;
    }
}
</style>